home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
filesys
/
ofake.zoo
/
src
/
fakefs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-17
|
8KB
|
393 lines
#include "atarierr.h"
#include "filesys.h"
#include <string.h>
#define DOM_TOS 0
#define DOM_MINT 1
#define NUM_DRIVES 32
#ifndef NULL
#define NULL 0L
#endif
/*
* this points to the structure that has all the useful functions that
* the kernel told us about
*/
struct kerinfo *kernel;
#define CCONWS (void)(*kernel->dos_tab[0x09])
#define FGETDTA (*kernel->dos_tab[0x2f])
#define RWABS (*kernel->bios_tab[4])
#define GETBPB (void *)(*kernel->bios_tab[7])
#define DEBUG (*kernel->debug)
#define ALERT (*kernel->alert)
#define TRACE (*kernel->trace)
#define FATAL (*kernel->fatal)
#define P_(x) ()
int fakedrv = 0;
long fake_root P_((int drv, fcookie *fc));
long fake_lookup P_((fcookie *dir, char *name, fcookie *fc));
long fake_getxattr P_((fcookie *fc, XATTR *xattr));
long fake_chattr P_((fcookie *fc, int attrib));
long fake_chown P_((fcookie *fc, int uid, int gid));
long fake_chmode P_((fcookie *fc, unsigned mode));
long fake_rmdir P_((fcookie *dir, char *name));
long fake_remove P_((fcookie *dir, char *name));
long fake_getname P_((fcookie *root, fcookie *dir, char *pathname));
long fake_rename P_((fcookie *olddir, char *oldname,
fcookie *newdir, char *newname));
long fake_opendir P_((DIR *dirh, int flags));
long fake_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *));
long fake_rewinddir P_((DIR *dirh));
long fake_closedir P_((DIR *dirh));
long fake_pathconf P_((fcookie *dir, int which));
long fake_dfree P_((fcookie *dir, long *buf));
DEVDRV * fake_getdev P_((fcookie *fc, long *devsp));
long fake_symlink P_((fcookie *dir, char *name, char *to));
long fake_readlink P_((fcookie *fc, char *buf, int buflen));
long fake_dskchng P_((int drv));
long errinvfn();
FILESYS fake_filesys = {
(FILESYS *)0,
0,
fake_root,
fake_lookup, errinvfn, fake_getdev, fake_getxattr,
fake_chattr, fake_chown, fake_chmode,
errinvfn, fake_rmdir, fake_remove, fake_getname, fake_rename,
fake_opendir, fake_readdir, fake_rewinddir, fake_closedir,
fake_pathconf, fake_dfree, errinvfn, errinvfn,
fake_symlink, fake_readlink, errinvfn, errinvfn, fake_dskchng
};
typedef long (*Longfunc)();
Longfunc oldgetbpb, oldmediach, oldrwabs;
extern long newrwabs(), newmediach(), newgetbpb(); /* see below */
/* struct used by Fsfirst/Fsnext */
typedef struct _dta {
char dta_buf[21];
char dta_attribute;
unsigned short dta_time;
unsigned short dta_date;
long dta_size;
char dta_name[14];
} _DTA;
/*
* this must be the first function; it is called by the kernel when the
* file system is being loaded, and should return the file system
* structure
*/
FILESYS *
fake_init(k)
struct kerinfo *k;
{
_DTA *d;
static char foo[] = "x:";
char drvlet;
kernel = k;
/* we decide which device is going to be fake based upon the
* name we were loaded with (available in the current DTA
* buffer)
*/
d = (_DTA *)FGETDTA();
drvlet = d->dta_name[0];
if (drvlet >= 'a' && drvlet <= 'z') {
fakedrv = drvlet - 'a';
} else {
fakedrv = drvlet - 'A';
}
foo[0] = fakedrv + 'A';
if (fakedrv < 0 || fakedrv > 15) {
CCONWS("Cannot install fake drive ");
CCONWS(foo);
CCONWS(" -- try renaming your .XFS file\r\n");
return 0;
}
if ( (*((long *)0x4c2)) & (1L << fakedrv) ) {
CCONWS("Drive "); CCONWS(foo);
CCONWS(" already exists -- it can't be made fake\r\n");
return 0;
}
/* install a fake BIOS device */
/* we also have to put in some fake drivers for Getbpb, etc */
oldrwabs = *((Longfunc *)0x476);
oldgetbpb = *((Longfunc *)0x472);
oldmediach = *((Longfunc *)0x47e);
*((Longfunc *)0x476) = newrwabs;
*((Longfunc *)0x472) = newgetbpb;
*((Longfunc *)0x47e) = newmediach;
*((long *)0x4c2) |= (1L << fakedrv);
CCONWS("Loaded fake universal device for drive ");
CCONWS(foo);
CCONWS("\r\n");
return &fake_filesys;
}
long
errinvfn()
{
DEBUG("Invalid function called on fake file system.");
return EINVFN;
}
/*
* this is rather ugly; what it does is step through the file system
* chain looking for the universal drive (drive U:), and if found
* it does a root directory lookup for that file system and returns the
* result. THIS MAY BREAK ON FUTURE VERSIONS OF MINT; I don't recommend
* that you rely on internals of the file system routines!!!!!
*/
#ifndef UNIDRV
#define UNIDRV 'U'-'A'
#endif
FILESYS *unifs;
long
fake_root(drv, fc)
int drv;
fcookie *fc;
{
fcookie dir;
if (drv == fakedrv) {
unifs = fake_filesys.next;
while (unifs) {
if ( (*unifs->root)(UNIDRV, fc) == 0 ) {
fc->fs = &fake_filesys;
fc->dev = fakedrv;
return 0;
}
unifs = unifs->next;
}
ALERT("Couldn't find file system for U:!");
}
fc->fs = 0;
return EDRIVE;
}
/*
* all the other fake function drivers just call out to the unified
* file system to do their stuff
*/
long
fake_lookup(dir, name, fc)
fcookie *dir, *fc; char *name;
{
if (!*name || (*name == '.' && (name[1] == 0 || name[1] == '.'))) {
*fc = *dir;
return 0;
}
return (*unifs->lookup)(dir, name, fc);
}
long
fake_getxattr(fc, xattr)
fcookie *fc; XATTR *xattr;
{
if (fc->index != 0L) {
ALERT("Bad getxattr call on fake file system");
return EFILNF;
}
xattr->index = fc->index;
xattr->dev = fc->dev;
xattr->nlink = 1;
xattr->blksize = 1;
xattr->uid = xattr->gid = 0;
xattr->size = xattr->nblocks = 0;
xattr->mode = S_IFDIR | 0777;
xattr->attr = FA_DIR;
xattr->mtime = xattr->atime = xattr->ctime = 0;
xattr->mdate = xattr->adate = xattr->cdate = 0;
return 0;
}
long
fake_chattr(fc, attrib)
fcookie *fc; int attrib;
{
return EACCDN;
}
long
fake_chown(fc, uid, gid)
fcookie *fc; int uid, gid;
{
return EACCDN;
}
long
fake_chmode(fc, mode)
fcookie *fc;
unsigned mode;
{
return EACCDN;
}
long
fake_rmdir(dir, name)
fcookie *dir;
char *name;
{
return (*unifs->rmdir)(dir, name);
}
long
fake_remove(dir, name)
fcookie *dir;
char *name;
{
return (*unifs->remove)(dir, name);
}
long
fake_getname(root, dir, name)
fcookie *root, *dir;
char *name;
{
fcookie realroot;
fcookie realdir;
(*unifs->root)(UNIDRV, &realroot);
realdir = *dir;
if (realdir.dev == fakedrv) {
realdir.dev = UNIDRV;
realdir.fs = unifs;
}
return (*unifs->getname)(&realroot, &realdir, name);
}
long
fake_rename(olddir, oldname, newdir, newname)
fcookie *olddir, *newdir;
char *oldname, *newname;
{
return (*unifs->rename)(olddir, oldname, newdir, newname);
}
long
fake_opendir(dirh, flags)
DIR *dirh; int flags;
{
return (*unifs->opendir)(dirh, flags);
}
long
fake_readdir(dirh, nm, nmlen, fc)
DIR *dirh; char *nm; int nmlen; fcookie *fc;
{
return (*unifs->readdir)(dirh, nm, nmlen, fc);
}
long
fake_rewinddir(dirh)
DIR *dirh;
{
return (*unifs->rewinddir)(dirh);
}
long
fake_closedir(dirh)
DIR *dirh;
{
return (*unifs->closedir)(dirh);
}
long
fake_pathconf(dir, which)
fcookie *dir; int which;
{
return (*unifs->pathconf)(dir, which);
}
long
fake_dfree(dir, buf)
fcookie *dir; long *buf;
{
return (*unifs->dfree)(dir, buf);
}
DEVDRV *
fake_getdev(fc, devsp)
fcookie *fc; long *devsp;
{
return (*unifs->getdev)(fc, devsp);
}
long
fake_symlink(dir, name, to)
fcookie *dir; char *name, *to;
{
return (*unifs->symlink)(dir, name, to);
}
long
fake_readlink(fc, buf, len)
fcookie *fc; char *buf; int len;
{
return (*unifs->readlink)(fc, buf, len);
}
long
fake_dskchng(drv)
int drv;
{
(void)GETBPB(drv);
return 0;
}
/*
* and here are the fake drivers for the BIOS
*/
asm
("\
.globl _newrwabs; \
.globl _newmediach; \
.globl _newgetbpb; \
_newgetbpb: \
movew sp@(4), d0; \
cmpw _fakedrv, d0; \
beq ret0; \
movel _oldgetbpb, a0; \
jmp a0@; \
ret0: \
clrl d0; \
rts; \
_newmediach: \
movew sp@(4), d0; \
cmpw _fakedrv, d0; \
beq ret0; \
movel _oldmediach, a0; \
jmp a0@; \
_newrwabs: \
movew sp@(0xe), d0; \
cmpw _fakedrv, d0; \
beq ret0; \
movel _oldrwabs, a0; \
j